// 引入Koa
import Koa from 'koa';
const app = new Koa();
// 引入react
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router';
import { matchPath, Switch, Route } from 'react-router-dom';
// 路由模块
import Router from 'koa-router';
const router = new Router();
// 静态资源
import path from 'path';
import serve from 'koa-static';
import staticUtil from './static';
import fs from 'fs';
// 路由
import routes from '../src/pages/routes';
// 引入redux
import { Provider } from 'react-redux';
import store from '../src/redux/store';
// 加载history
import history from '../src/utils/history';
import App from '../src/App';

// 静态页转换
const injectHTML = (data, { title, body, scripts, state }) => {
  data = data.replace(/<title>.*?<\/title>/g, title);
  data = data.replace(/<body[^>]*>([\s\S]*)<\/div>/, `<body>
    <noscript>请让浏览器允许运行js，以便打开网站内容</noscript>
    <div id="root">${body}</div><script>window.__PRELOADED_STATE__ = ${state}</script>`
  );
  return data;
};

// 静态资源
const staticPath = async (ctx, next) => {
  // 静态资源目录在本地的绝对路径
  let fullStaticPath = path.join(__dirname, '../build')

  // 获取静态资源内容，有可能是文件内容，目录，或404
  let _content = await staticUtil.content(ctx, fullStaticPath)
  // 解析请求内容的类型
  let _mime = staticUtil.parseMime(ctx.url)

  // 如果有对应的文件类型，就配置上下文的类型
  if (_mime) {
    ctx.type = _mime
  }

  // 输出静态资源内容
  if (_mime && _mime.indexOf('image/') >= 0) {
    // 如果是图片，则用node原生res，输出二进制数据
    ctx.res.writeHead(200)
    ctx.res.write(_content, 'binary')
    ctx.res.end()
  } else {
    // 其他则输出文本
    ctx.body = _content
  }
}
router.get('/static/*', async (ctx, next) => {
  staticPath(ctx, next);
});
router.get('/json/*', async (ctx, next) => {
  staticPath(ctx, next);
});
router.get('/images/*', async (ctx, next) => {
  console.log('images');
  staticPath(ctx, next);
});

app.use(async (ctx, next)=>{
  await next()
})

app.use(router.routes())
app.use(router.allowedMethods());

router.get('/*', async (ctx, next) => {
  const context = {};
  const htmlRender = ReactDOMServer.renderToString(
    <Provider store={store}>
      <StaticRouter
        location={ctx.request.url}
        context={context}
        history={history}>
        <Route component={App}></Route>
      </StaticRouter>
    </Provider>
  )
  // // 路由
  const promises = [];
  routes.some(route => {
    const match = matchPath(ctx.request.url, route)
    if (match)
      promises.push(route.loadData(match))
    return match
  })
  const data = await Promise.all(promises).then(data => {
    return data
  })
  console.log('data',data);
  const renderData = () => {
    return new Promise((resolve, reject) => {
      fs.readFile(path.resolve(__dirname, '../build/index.html'), 'utf-8', (err, htmlData) => {
         if(err){
           reject(err);
         }else {
           resolve(htmlData);
         }
      });
    })
  }
  let htmlData = await renderData();
  const html = injectHTML(htmlData, {
    title: '<title>我是标题</title>',
    body: htmlRender,
    scripts: [],
    state: '33'
  });

  ctx.response.body = html;
});

// 监听网页端口
app.listen(3002);
